package com.bj58.ecdata.calc.dbservice.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Tuple;

import com.bj58.ecdata.calc.dbservice.consts.Constant;
import com.bj58.ecdata.calc.dbservice.dao.ResumeAddDao;
import com.bj58.ecdata.calc.dbservice.dao.model.DataPoint;
import com.bj58.ecdata.calc.dbservice.dao.model.ResumeAddModel;
import com.bj58.ecdata.calc.dbservice.load.SpringUtils;
import com.bj58.ecdata.calc.dbservice.model.ResultObj;
import com.bj58.ecdata.calc.dbservice.model.ResultPoint;
import com.bj58.ecdata.calc.dbservice.service.ResumeAddService;
import com.bj58.ecdata.exception.BusinessException;
import com.bj58.ecdata.util.DateUtils;
import com.bj58.ecdata.util.JsonUtils;
import com.bj58.spat.scf.server.contract.annotation.ServiceBehavior;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@ServiceBehavior
public class ResumeAddServiceImpl implements ResumeAddService{
	Logger log = LoggerFactory.getLogger(ResumeAddServiceImpl.class);
	private List<String> types;
	private List<String> divTypes = Lists.newArrayList();
	private ResumeAddDao dao = SpringUtils.getInstance().getBean(ResumeAddDao.class);

	public ResumeAddServiceImpl() {
		types = Lists.newArrayList("infoNum");
	}

	@Override
	public String getDailySum(String platform) {
		ResumeAddModel model = new ResumeAddModel();
		model.setTime(DateUtils.getTruncatedToday());
		model.setPlatform(StringUtils.isBlank(platform) ? null : platform );

		long addNum = dao.loadDailySum("addNum", model);

		DataPoint dataPoint = new DataPoint();
		dataPoint.setTime(dao.getLatest());
		dataPoint.setValue(addNum);
		return JsonUtils.toJson(dataPoint);
	}

	@Override
	public String getData(String type, String platform, long time) {

		checkType(type);

		long endTime = dao.getLatest();
		List<ResumeAddModel> params = createModels(time, endTime, Constant._2s, Constant._1h, platform);
		List<DataPoint> datas = dao.load(type, params, isDiv(type));
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}

	@Override
	public String getDataTodayHourly(String type, String platform) {

		checkType(type);

		long zeroTime = DateUtils.getTruncatedToday();
		long curTime = dao.getLatest();
		long endTime = DateUtils.truncateToHour(curTime) - Constant._1h;
		List<ResumeAddModel> params = createModels(0, endTime, Constant._1h, endTime - zeroTime + Constant._1h, platform);
		List<DataPoint> datas = dao.loadHourly(type, params, isDiv(type));
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}

	@Override
	public String getDataYesterdayHourly(String type, String platform) {

		checkType(type);

		long endTime = DateUtils.getTruncatedToday() - Constant._1h;
		List<ResumeAddModel> params = createModels(0, endTime, Constant._1h, Constant._1d, platform);
		List<DataPoint> datas = dao.loadHourly(type, params, isDiv(type));
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}


	@Override
	public String getTopCateList(String platform, int count) {
		if (count < 1) {
			count = 1;
		}
		ResultObj result = new ResultObj();
		result.setData(getTopCateData(platform, count));
		return JsonUtils.toJson(result);
	}
	
	@Override
	public String getTopCateList(int count) {
		if (count < 1) {
			count = 1;
		}
		Map<String, Map<String, Object>> resultMap = Maps.newHashMap();
		
		ResumeAddModel model = new ResumeAddModel();
		model.setTime(DateUtils.getTruncatedToday());
		//取TOPN 和 当前总量
		Map<String, Object> rsMap = Maps.newHashMap();
		//top N
		rsMap.put("data", getTopCateData(null,count));
		// total
		rsMap.put("total", dao.loadDailySum("addNum", model));
		
		resultMap.put("jianli", rsMap);
		return JsonUtils.toJson(resultMap);
	}
	

	/**
	 * 获取TOP N
	 */
	private List<ResultPoint> getTopCateData(String platform,  int count) {
		if (count < 1) {
			count = 1;
		}
		ResumeAddModel model = new ResumeAddModel();
		model.setTime(DateUtils.getTruncatedToday());
		model.setPlatform(StringUtils.isBlank(platform) ? null : platform);
		Set<Tuple> tuples = dao.loadTopCateList(model, count);
		List<ResultPoint> datas = Lists.newArrayList();
		for (Tuple tuple : tuples) {
			ResultPoint data = new ResultPoint();
			data.setType(tuple.getElement());
			data.setValue((long) tuple.getScore());
			datas.add(data);
		}
		return datas;
	}
	
	private List<ResumeAddModel> createModels(long startTime, long endTime, long interval, long span, String platform) {
		long minTime = endTime - span;
		if (startTime == 0 || startTime < minTime) {
			startTime = minTime;
		}

		List<ResumeAddModel> models = Lists.newArrayList();
		for (long i = startTime + interval; i <= endTime; i += interval) {
			ResumeAddModel model = new ResumeAddModel();
			model.setTime(i);
			model.setPlatform(StringUtils.isBlank(platform) ? null : platform);
			models.add(model);
		}
		return models;
	}

	protected void checkType(String type) {
		if (!types.contains(type)) {
			throw new BusinessException("error type! (%s)", type);
		}
	}

	protected boolean isDiv(String type) {
		return divTypes.contains(type);
	}

	@Override
	public String ping() {
		return "PONG";
	}
}
